package com.glSto.service;

import com.glSto.rep.BomResponse;
import com.glSto.req.BomRequest;
import com.glSto.req.BomSendRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.stereotype.Service;
import org.springframework.web.client.ResourceAccessException;
import org.springframework.web.client.RestTemplate;

import javax.annotation.PostConstruct;
import java.util.Base64;
import java.util.List;

@Service
public class BomService {
    private static final Logger poCallbackLogger = LoggerFactory.getLogger("com.glSto.controller.MdmController.poCallback");

    // BOM接口地址
    @Value("${mdm.bom.request-api-url}")
    private String bomRequestApiUrl;

    @Value("${mdm.bom.api-url}")
    private String bomApiUrl;

    @Value("${mdm.basicAuth.username}")
    private String userName;

    @Value("${mdm.basicAuth.password}")
    private String passWord;

    /**
     * 调用BOM接口（获取数据，保持不变）
     */
    public int getBOMData(BomRequest request) {
        String auth = userName + ":" + passWord;
        byte[] encodedAuth = Base64.getEncoder().encode(auth.getBytes());
        String authHeader = "Basic " + new String(encodedAuth);

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.set("Authorization", authHeader);

        HttpEntity<BomRequest> requestEntity = new HttpEntity<>(request, headers);

        poCallbackLogger.info("开始发送bom请求：{}", headers);
        RestTemplate restTemplate = new RestTemplate();
        try {
            ResponseEntity<BomResponse> responseEntity = restTemplate.postForEntity(bomRequestApiUrl, requestEntity, BomResponse.class);
            poCallbackLogger.info("BOM响应体：{}", responseEntity.getBody());

            // 检查HTTP状态码，202表示成功
            if (responseEntity.getStatusCodeValue() == 202) {
                poCallbackLogger.info("BOM接口调用成功，等待对方平台回调");
                return 1;
            } else {
                poCallbackLogger.info("BOM接口调用，HTTP状态码: {}", responseEntity.getStatusCodeValue());
                return -1;
            }
        } catch (Exception e) {
            poCallbackLogger.error("调用BOM接口时发生异常: ", e);
            return -1;
        }
    }


    // 配置参数（保留批量大小和超时，移除线程池参数）
    private static final int BATCH_SIZE = 50;  // 每批处理50条
    private static final int CONNECT_TIMEOUT = 15000;
    private static final int READ_TIMEOUT = 60000;
    private static final int RETRY_COUNT = 2;   // 单条失败重试次数
    private static final long RETRY_DELAY = 2000;  // 重试间隔（毫秒）

    // 仅保留RestTemplate（单线程无需线程池）
    private RestTemplate restTemplate;

    @PostConstruct
    public void init() {
        // 初始化RestTemplate（单线程共用一个实例）
        restTemplate = new RestTemplate();
        SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
        requestFactory.setConnectTimeout(CONNECT_TIMEOUT);
        requestFactory.setReadTimeout(READ_TIMEOUT);
        restTemplate.setRequestFactory(requestFactory);
        poCallbackLogger.info("RestTemplate初始化完成 - 连接超时: {}ms, 读取超时: {}ms", CONNECT_TIMEOUT, READ_TIMEOUT);
    }

    /**
     * 单线程批量发送BOM数据（核心修改：移除异步，改为同步批处理）
     */
    public String sendBomData(List<BomSendRequest> bomRequests) {
        long startTime = System.currentTimeMillis();
        poCallbackLogger.info("=== 开始单线程批量发送BOM数据 ===");

        try {
            if (bomRequests == null || bomRequests.isEmpty()) {
                poCallbackLogger.warn("未提供BOM数据");
                return "处理完成，无有效数据";
            }

            int total = bomRequests.size();
            poCallbackLogger.info("获取到 {} 条BOM数据，开始批处理", total);

            // 统计成功/失败数量
            int totalSuccess = 0;
            int totalFailure = 0;

            // 计算总批次数
            int batchCount = (total + BATCH_SIZE - 1) / BATCH_SIZE;
            poCallbackLogger.info("总批次数: {}", batchCount);

            // 按批次同步处理
            for (int batchNum = 0; batchNum < batchCount; batchNum++) {
                int startIdx = batchNum * BATCH_SIZE;
                int endIdx = Math.min((batchNum + 1) * BATCH_SIZE, total);
                List<BomSendRequest> batch = bomRequests.subList(startIdx, endIdx);

                long batchStartTime = System.currentTimeMillis();
                poCallbackLogger.info("批次[{}] 开始处理（{}条，范围：{}-{}）",
                        batchNum + 1, batch.size(), startIdx + 1, endIdx);

                // 处理当前批次的每条数据
                for (BomSendRequest request : batch) {
                    // 单条处理带重试
                    boolean success = processSingleRequestWithRetry(request);
                    if (success) {
                        totalSuccess++;
                    } else {
                        totalFailure++;
                    }
                }

                poCallbackLogger.info("批次[{}] 处理完成 - 成功: {}, 失败: {}, 耗时: {}ms",
                        batchNum + 1,
                        (totalSuccess - (batchNum * BATCH_SIZE > 0 ? totalSuccess - batch.size() : 0)),  // 本批成功数
                        (totalFailure - (batchNum * BATCH_SIZE > 0 ? totalFailure - (batch.size() - (totalSuccess - (totalSuccess - batch.size()))) : 0)),  // 本批失败数
                        System.currentTimeMillis() - batchStartTime);
            }

            // 总结果
            return String.format("处理完成 - 总数据: %d, 成功: %d, 失败: %d, 总耗时: %dms",
                    total, totalSuccess, totalFailure, System.currentTimeMillis() - startTime);

        } catch (Exception e) {
            poCallbackLogger.error("批量发送BOM数据失败", e);
            return "发送数据失败：" + e.getMessage();
        } finally {
            poCallbackLogger.info("=== 单线程批处理总耗时: {}ms ===", System.currentTimeMillis() - startTime);
        }
    }

    /**
     * 单条数据处理（带重试机制）
     */
    private boolean processSingleRequestWithRetry(BomSendRequest request) {
        for (int retry = 0; retry <= RETRY_COUNT; retry++) {
            try {
                // 第1次重试时打印日志
                if (retry > 0) {
                    poCallbackLogger.info("第{}次重试处理数据: {}", retry, request);
                }
                return processSingleRequest(request);
            } catch (Exception e) {
                // 最后一次重试失败则返回false
                if (retry == RETRY_COUNT) {
                    poCallbackLogger.error("数据处理失败（已达最大重试次数）: {}", request, e);
                    return false;
                }
                // 非最后一次重试则等待后继续
                try {
                    Thread.sleep(RETRY_DELAY);
                } catch (InterruptedException ie) {
                    Thread.currentThread().interrupt();
                    return false;
                }
            }
        }
        return false;
    }

    /**
     * 实际发送单条数据（逻辑不变，仅作为重试的基础方法）
     */
    private boolean processSingleRequest(BomSendRequest request) {
        try {
            // 构建请求头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);

            // 构建请求体
            HttpEntity<BomSendRequest> entity = new HttpEntity<>(request, headers);

            poCallbackLogger.info("发送BOM数据 - 请求: {}", request);
            // 调用目标接口并解析响应
            ResponseEntity<String> response = restTemplate.exchange(
                    bomApiUrl,
                    HttpMethod.POST,
                    entity,
                    String.class
            );

            // 判断是否成功
            if (response.getStatusCode().is2xxSuccessful()) {
                String responseBody = response.getBody();
                poCallbackLogger.info("BOM数据发送成功 - 响应: {}", responseBody);
                return true;
            } else {
                poCallbackLogger.error("BOM数据发送失败 - HTTP状态码: {}, 响应: {}",
                        response.getStatusCodeValue(), response.getBody());
                return false;
            }

        } catch (ResourceAccessException e) { // 网络异常（超时、连接失败）
            poCallbackLogger.error("BOM数据网络异常: {}", e.getMessage());
            return false;
        } catch (Exception e) { // 其他异常（解析失败、参数错误等）
            poCallbackLogger.error("BOM数据处理异常", e);
            return false;
        }
    }
}